﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.Timers;
 
namespace wifi_test
{
    public partial class Form1 : Form
    {
        cls_testnet cls_net;
        Thread udpRecThread;
        Thread udpSendThread;
        public enum LogMsgType { Incoming, Outgoing, Normal, Warning, Error, Custom, Receve };
        public Color[] LogMsgTypeColor = { Color.Orange, Color.Green, Color.White, Color.Brown, Color.Red, Color.Yellow, Color.Blue };
        private object lockForWrite = new object();
        public enum TestState { idle, handshake, testing, sendhandshake };
        TestState runState = TestState.idle;
        int dispTime;

        public System.Timers.Timer runTimeOverTimer;
        public System.Timers.Timer dispLogTimer;

        private bool _isRuning = false;

        public  Form1()
        {
            InitializeComponent();

            #region 窗体控件的初始化
            //窗体控件的初始化部份
            comboBox1.Items.Clear();
            comboBox1.Items.Add("连续测试");
            comboBox1.Items.Add("指定测试次数");
            comboBox1.SelectedIndex = 0;

            String xustr = System.Net.Dns.GetHostName();

            System.Net.IPAddress addr;

            // 获得本机局域网IP地址

            addr = new System.Net.IPAddress(Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].Address);
            xustr = addr.ToString();

            localIp_TextBox.Text = xustr;
            runTimeOverTimer = new System.Timers.Timer();
            runTimeOverTimer.Elapsed += new ElapsedEventHandler(runTimeOverTimer_Elapsed);

            dispLogTimer = new System.Timers.Timer();
            dispLogTimer.Elapsed += new ElapsedEventHandler(dispLogTimer_Elapsed);

            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_Closing);

            dispTime = trackBar1.Value;

            cls_net = new cls_testnet(this);

            #region 读取配置文件

            cls_ReadSetup xuReadSetup = new cls_ReadSetup();

            if (xuReadSetup.fun_SetupFileExist())
            {
                
            }

            #endregion

            #endregion
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            #region 选择测试方式
            //用于选择测试的方式
            //有连续测试与指定测试次数两种
            #endregion
            //string xu_str = comboBox1.

        }


        /// <summary>
        /// 关闭窗口时发生的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            //if(recThread

        }



        /// <summary>
        /// 测试用的按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            cls_testnet cls_net = new cls_testnet(this);

            try
            {
                cls_net.fun_InitSendInterface(dstip_text.Text, Convert.ToInt32(dstport_text.Text));
            }
            catch (Exception xe)
            {
                Console.WriteLine("The process failed: {0}", xe.ToString());
                return;
            }


            try
            {
                cls_net.fun_InitRecInterface(localIp_TextBox.Text, Convert.ToInt32(localport_text.Text));
            }
            catch (Exception xe)
            {
                Console.WriteLine("The process failed: {0}", xe.ToString());
                return;
            }
            byte [] data_sp = cls_net.fun_CreateFrame(7);
            cls_net.sub_SendFrame(data_sp);
        }


        /// <summary>
        /// 初始化完后与下位机进行握手
        /// </summary>
        /// 1、向下位机发送are you ready信息
        /// 2、下位机接收到are you ready信息后，向上位机发送ok帧
        /// 3、上位机接收到ok帧后认为握手成功
        /// <returns></returns>
        private bool fun_ReadyStartTest()
        {
            bool retflag;
            string xustr = "ready?";

            //以下要启动接收线程了
            udpRecThread = new Thread(new ParameterizedThreadStart(this.recThread));
            udpRecThread.IsBackground = true;

            //以下是要准备发送线程，但不启动
            udpSendThread = new Thread(new ParameterizedThreadStart(this.sendThread));
            udpSendThread.IsBackground = true;

            if (runState != TestState.sendhandshake)
            {

                byte[] data_sp = System.Text.Encoding.Default.GetBytes(xustr);
                // = new byte[] { 'a', 1, 2, 3, 4, 5 }; 

                cls_net.sub_SendFrame(data_sp);

                runTimeOverTimer.Enabled = false;
                runTimeOverTimer.Interval = 1000 * 6; //6秒
                runTimeOverTimer.Enabled = true;

                udpRecThread.Start(0);

                retflag = true;

                runState = TestState.handshake;
            }
            else
            {
                udpRecThread.Start(0);
                retflag = true;
            }

            return retflag;
        }



        /// <summary>
        /// 开始测试按钮按下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            bool retflag;

            if (_isRuning == false)
            {
                checkBox1.Enabled = false;
                try
                {
                    retflag = cls_net.fun_InitSendInterface(dstip_text.Text, Convert.ToInt32(dstport_text.Text));
                }
                catch (Exception xe)
                {
                    Console.WriteLine("The process failed: {0}", xe.ToString());
                    checkBox1.Enabled = true;
                    return;
                }

                if (retflag == false)
                {
                    checkBox1.Enabled = true;
                    return;
                }


                try
                {
                    retflag = cls_net.fun_InitRecInterface(localIp_TextBox.Text, Convert.ToInt32(localport_text.Text));
                }
                catch (Exception xe)
                {
                    Console.WriteLine("The process failed: {0}", xe.ToString());
                    checkBox1.Enabled = true;
                    return;
                }

                if (retflag == false)
                {
                    checkBox1.Enabled = true;
                    return;
                }

                string str = System.DateTime.Now.ToString();
                xulog(LogMsgType.Incoming, "准备开始进行测试" + "\n");

                retflag = fun_ReadyStartTest();
                button2.Text = "停止测试";
                _isRuning = true;
            }
            else
            {
                sub_stoptest(0);
            }

        }


        /// <summary>
        /// 接收UDP的线程
        /// </summary>
        /// <param name="param"></param>
        public void recThread(Object param)
        {
            byte[] recbuf = null;
            int i;

            while (true)
            {
                recbuf = cls_net.fun_RecDstData();
                if (recbuf != null)
                {
                    i = cls_net.fun_AnalyFrame(recbuf, runState);
                    if (i == 100)
                    {
                        //表示握手成功了
                        runState = TestState.testing;
                        runTimeOverTimer.Enabled = false;  //停止主定时器
                        udpSendThread.Start(0);
                        if (dispTime == 0)
                        {
                            dispTime = 1;
                        }
                        dispLogTimer.Interval = dispTime * 60 * 1000;
                        dispLogTimer.Enabled = true;
                        xulog(LogMsgType.Incoming, "握手成功！！！" + "\n");
                        cls_net.record_cls.sub_recordin(cls_record.recordstate.starttest, " ");
                        cls_net.sub_SetRecFrameNo(-1);
                        cls_net.recErrors = 0;
                    }
                }
                else
                {
                    sub_stoptest(1);
                    return;
                }
            }
        }


        /// <summary>
        /// 发送UDP的线程
        /// </summary>
        /// <param name="param"></param>
        public void sendThread(Object param)
        {
            int i;
            byte[] sendbuf;

            i = cls_net.sendPackets;
            while (true)
            {
                if (i > 9)
                {
                    i = i % 10;
                }

                sendbuf = cls_net.fun_CreateFrame(Convert.ToByte(i));
                if (sendbuf != null)
                {
                    cls_net.sub_SendFrame(sendbuf);
                    //Thread.Sleep(1);   //停下10ms
                    Thread.Sleep(1);       
                }
                i += 1;
                cls_net.sendPackets = cls_net.sendPackets + 1;
            }
        }

        public delegate void CLog(LogMsgType msgtype, string msg);

        /// <summary>
        /// 日志记录方法
        /// </summary>
        /// <param name="msgtype">字体颜色</param>
        /// <param name="msg">文字消息</param>
        /// <param name="flag">字体颜色</param>
        public void Log(LogMsgType msgtype, string msg)
        {
            lock (lockForWrite)
            {

                if (!testInfo.InvokeRequired)
                {
                    if (testInfo.Lines.Length > 1000)
                    {
                        testInfo.Clear();
                    }
                    testInfo.SelectedText = string.Empty;
                    testInfo.SelectionFont = new Font(testInfo.SelectionFont, FontStyle.Bold);
                    testInfo.SelectionColor = LogMsgTypeColor[(int)msgtype];
                    testInfo.AppendText(msg);
                    testInfo.ScrollToCaret();
                }
                else
                {
                    CLog _Log = new CLog(Log);
                    testInfo.BeginInvoke(_Log, new object[] { msgtype, msg });
                }
            }
        }


        /// <summary>
        /// 运行时的主超时器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void runTimeOverTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            System.Timers.Timer handleTimer = (System.Timers.Timer)sender;

            handleTimer.Enabled = false;
            switch (runState)
            {
                case TestState.handshake:
                    //握手时发生的超时
                    xulog(LogMsgType.Error, "握手发生超时......" + "\n");

                    string xustr = "ready?";

                    byte[] data_sp = System.Text.Encoding.Default.GetBytes(xustr);
                    // = new byte[] { 'a', 1, 2, 3, 4, 5 }; 

                    cls_net.sub_SendFrame(data_sp);

                    handleTimer.Interval = 6 * 1000;
                    handleTimer.Enabled = true;
                    break;
            }
        }


        /// <summary>
        /// 显示日志内容的定时器
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void dispLogTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            System.Timers.Timer handleTimer = (System.Timers.Timer)sender;

            handleTimer.Enabled = false;

            uint i = (uint)cls_net.sendPackets;
            uint j = (uint)cls_net.recPackets;

            string xustr = "发送了" + i.ToString() + "包" + "--接收了" + j.ToString() + "包";
            xustr += "--接收发错了" + cls_net.recErrors.ToString() + "包" + "--发送出错了" + cls_net.sendErrors.ToString() + "包"
                     +  "--掉失" + cls_net.recMiss.ToString();
            //string xustr = "111111";
            xulog(LogMsgType.Incoming, xustr + "\n");

            uint x, z;

            if (i > 1024 * 10)
            {
                x = ((i / 1024) * 1021) / 1024;
            }
            else
            {
                x = (i * 1021) / (1024 * 1024);
            }

            if (j > 1024 * 10)
            {
                z = ((j / 1024) * 1021) / 1024;
            }
            else
            {
                z = (j * 1021) / (1024 * 1024);
            }
            string xustr1 = "发送" + x.ToString() + "M的数据" + "--接收了" + z.ToString() + "M的数据" + "\n";
            xulog(LogMsgType.Outgoing, xustr1);

            handleTimer.Interval = dispTime * 60 * 1000;
            handleTimer.Enabled = true;
        }


        /// <summary>
        /// 在记录的信息前加入，事件发生的时间
        /// </summary>
        /// <param name="msgtype"></param>
        /// <param name="msg"></param>
        public void xulog(LogMsgType msgtype, string msg)
        {
            string newstr = System.DateTime.Now.ToString() + "--" + msg;
            Log(msgtype, newstr);
        }

        /// <summary>
        /// 日志显示时间的设置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void trackBar1_Scroll(object sender, EventArgs e)
        {            
            int i = trackBar1.Value;

            dispTime = i;

            label7.Text = i.ToString() + "分钟";
        }


        //public delegate void CStopTest();
        /// <summary>
        /// 停止测试
        /// </summary>
        /// flag为0表示要关闭两个线程
        /// flag为1表示要关闭发送线程
        /// flag为2表示要关闭接收线程
        public void sub_stoptest(int flag)
        {
            xulog(LogMsgType.Incoming, "停止测试" + "\n");
            _isRuning = false;
            if (flag == 0)
            {
                if (udpRecThread.IsAlive)
                {
                    udpRecThread.Abort();
                }
                if (udpSendThread.IsAlive)
                {
                    udpSendThread.Abort();
                }
            }
            else if (flag == 1)
            {
                if (udpSendThread.IsAlive)
                {
                    udpSendThread.Abort();
                }
            }
            else if (flag == 2)
            {
                if (udpRecThread.IsAlive)
                {
                    udpRecThread.Abort();
                }
            }
            runState = TestState.idle;
            cls_net.sub_reinit();
            runTimeOverTimer.Enabled = false;
            dispLogTimer.Enabled = false;

            uint i = (uint)cls_net.sendPackets;
            uint j = (uint)cls_net.recPackets;

            xulog(LogMsgType.Warning, "\n--------------------\n");
            string xustr = "发送了" + i.ToString() + "包" + "--接收了" + j.ToString() + "包";
            xustr += "--接收发错了" + cls_net.recErrors.ToString() + "包" + "--发送出错了" + cls_net.sendErrors.ToString() + "包" + 
                      "--掉失" + cls_net.recMiss.ToString();
            //string xustr = "111111";
            xulog(LogMsgType.Incoming, xustr + "\n");

            uint x, z;

            if (i > 1024 * 10)
            {
                x = ((i / 1024) * 1021) / 1024;
            }
            else
            {
                x = (i * 1021) / (1024 * 1024);
            }

            if (j > 1024 * 10)
            {
                z = ((j / 1024) * 1021) / 1024;
            }
            else
            {
                z = (j * 1021) / (1024 * 1024);
            }
            string xustr1 = "发送" + x.ToString() + "M的数据" + "--接收了" + z.ToString() + "M的数据" + "\n";
            xulog(LogMsgType.Outgoing, xustr1);
            xulog(LogMsgType.Warning, "--------------------\n\n");

            //cls_net.record_cls.sub_recordin(cls_record.recordstate.endtest, "--总共发送了" + i.ToString() + "--总共接收了" 
            //                                + j.ToString() + "--接收出错" + cls_net.sendErrors.ToString() + "--掉失" + cls_net.recMiss.ToString());
            cls_net.record_cls.sub_recordin(cls_record.recordstate.endtest, "--总共发送了" + i.ToString() + "--总共接收了"
                                            + j.ToString() + "--接收出错" + cls_net.sendErrors.ToString());
            sub_modbuttontext("开始测试");
        }


        /// <summary>
        /// 用于托管的修改开始测试的text
        /// </summary>
        /// <param name="msg"></param>
        public delegate void CStartText(string msg);
        public void sub_modbuttontext(string msg)
        {
            if (!button2.InvokeRequired)
            {
                button2.Text = msg;
                cls_net.record_cls.sub_genrecordfile();
                checkBox1.Enabled = true;
            }
            else
            {
                CStartText _Log = new CStartText(sub_modbuttontext);
                testInfo.BeginInvoke(_Log, msg);
            }
        }


        /// <summary>
        /// 用于PC对测的选项的改变
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.CheckState == CheckState.Checked)
            {
                runState = TestState.sendhandshake;
            }
            else
            {
                runState = TestState.idle;
            }
        }
       
    }
}
